﻿// Copyright (c) 2014 Morten Bakkedal
// This code is published under the MIT License.

using System;

using FuncLib.DualFunctions.Expressions;

namespace FuncLib.DualFunctions.Compilation
{
	internal class GradientLoopTerm : LoopTerm, IEquatable<GradientLoopTerm> 
	{
		private GeneratedFunction function;
		private SortedGradient gradient;
		private string generatedCode;

		private GradientLoopTerm(GeneratedFunction function, Expression expression, SortedGradient gradient)
			: base(expression)
		{
			this.function = function;
			this.gradient = gradient;
		}

		public static GradientLoopTerm Create(GeneratedFunction function, Expression expression, SortedGradient gradient)
		{
			return new GradientLoopTerm(function, expression, gradient);
		}

		public override void Prepare(FunctionBody body)
		{
			StorageOffsetsReference z = body.AddOffsets(gradient.GetIndexList(function.FunctionValueStorage.Index, function.Gradient, function.GradientStorage));
			generatedCode = "a[" + body.GetInnerFunctionIdentifier(function) + " + " + z.Identifier + "[i]]";
		}

		public override string GenerateArrayCode()
		{
			return generatedCode;
		}

		public bool Equals(GradientLoopTerm other)
		{
			return gradient.Equals(other.gradient);
		}

		public override int GetHashCode()
		{
			return gradient.GetHashCode();
		}

		public SortedGradient Gradient
		{
			get
			{
				return gradient;
			}
		}
	}
}
